﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package zasp.Classes {
    import flash.utils.*;
    import zasp.Util.*;
    import flash.external.*;

    public class ZaspTrackerGPI {

        private static var waitHandle:int = 1;
        private static var m_logOnce:Boolean = false;

        private var m_uiWaitHandle:int = 0;
        private var m_userWait:Boolean = false;
        private var m_activeWFs:Dictionary;
        private var m_activeWaits:Dictionary;
        protected var m_numActiveWaits:int = 0;
        protected var m_numActiveSTPWaits:int = 0;
        protected var m_waitStartTime:int = 0;
        protected var m_sTPWaitStartTime:int = 0;
        protected var m_totalWaitTime:int = 0;
        protected var m_sTPWaitTime:int = 0;
        protected var m_numWFs:int = 0;
        protected var m_numWaits:int = 0;
        protected var m_numSTPs:int = 0;
        protected var m_numLoads:int = 0;
        protected var m_numDialogs:int = 0;
        protected var m_numUnknownWaits:int = 0;
        private var m_queuedMessages:Array;
        private var m_sessionStartTime:int = 0;
        private var m_sessionid:String;
        private var m_failedInit:Boolean = false;
        private var m_trackAMFTotalWait:Boolean = true;
        protected var m_waitHandleDict:Dictionary;
        private var m_numPopups:int = 0;
        private var m_numClicks:int = 0;
        private var m_loadTime:int = 0;
        private var m_ignoreWait:Boolean = false;
        protected var m_active:Boolean = false;
        private var m_sessionInterval:int = 0;
        private var m_lastSession:int = 0;
        protected var m_f2f:Number;
        protected var m_mem:Number;
        protected var m_oef:Number;
        private var m_sendSessionMessage:Boolean = true;
        private var m_sendWaitMessage:Boolean = true;
        private var m_sendWFMessage:Boolean = true;
        private var m_componentInitTimes:Object = null;

        public function ZaspTrackerGPI(_arg1:String, _arg2:int=5000, _arg3:Boolean=false){
            if (ExternalInterface.available){
                ExternalInterface.addCallback("waitStateChange", this.waitStateChange);
                ExternalInterface.addCallback("gameStateChange", this.zaspWorkFlowEvent);
                this.m_sessionStartTime = 0;
                this.m_waitHandleDict = new Dictionary();
                this.m_activeWFs = new Dictionary();
                this.m_activeWaits = new Dictionary();
                this.m_queuedMessages = new Array();
                this.m_sessionInterval = _arg2;
                this.m_sessionid = _arg1;
                this.m_trackAMFTotalWait = _arg3;
            } else {
                this.m_failedInit = true;
                this.m_active = false;
                trace("ERROR:ZaspGPIManager external interface failed to init");
            };
        }
        public function report():Object{
            var _local1:Object;
            if (this.m_queuedMessages.length > 0){
                _local1 = new Object();
                _local1.type = "GPI";
                _local1.data = this.m_queuedMessages;
                this.m_queuedMessages = new Array();
            };
            return (_local1);
        }
        public function sample():void{
            var _local1:int;
            if (this.m_lastSession == 0){
                this.m_lastSession = getTimer();
                this.queueSessionReport();
            } else {
                _local1 = getTimer();
                if ((_local1 - this.m_lastSession) > this.m_sessionInterval){
                    this.queueSessionReport();
                    this.m_lastSession = _local1;
                    if (((this.m_componentInitTimes) && (m_logOnce))){
                        this.queueMessage(this.m_componentInitTimes);
                        m_logOnce = false;
                    };
                };
            };
        }
        public function popup():void{
            this.m_numPopups++;
        }
        public function click():void{
            this.m_numClicks++;
        }
        public function trackLoadTimingStart(_arg1:String):void{
            if (_arg1){
                if (!this.m_componentInitTimes){
                    this.m_componentInitTimes = new Object();
                };
                this.m_componentInitTimes["type"] = "loadstats";
                this.m_componentInitTimes[_arg1] = getTimer();
            };
        }
        public function trackLoadTimingStop(_arg1:String):void{
            if (_arg1){
                if (((this.m_componentInitTimes) && (this.m_componentInitTimes[_arg1]))){
                    this.m_componentInitTimes[_arg1] = (getTimer() - this.m_componentInitTimes[_arg1]);
                };
            };
        }
        public function interactive():void{
            this.m_loadTime = getTimer();
            this.m_sessionStartTime = this.m_loadTime;
            m_logOnce = true;
            if (this.m_numActiveSTPWaits){
                this.m_waitStartTime = this.m_loadTime;
            };
            if (this.m_numActiveWaits){
                this.m_sTPWaitStartTime = this.m_loadTime;
            };
        }
        public function activate(_arg1:Boolean, _arg2:Boolean, _arg3:Boolean):void{
            if (((!(this.m_active)) && (!(this.m_failedInit)))){
                this.m_active = true;
                this.m_sendSessionMessage = _arg1;
                this.m_sendWaitMessage = _arg2;
                this.m_sendWFMessage = _arg3;
            };
        }
        public function deactivate():void{
            if (((this.m_active) && (!(this.m_failedInit)))){
                this.m_active = false;
            };
        }
        private function queueMessage(_arg1:Object):void{
            this.m_queuedMessages.push(_arg1);
        }
        public function ignoreWaits(_arg1:Boolean):void{
            this.m_ignoreWait = _arg1;
        }
        public function waitsDisabled():Boolean{
            return (this.m_ignoreWait);
        }
        private function queueWFMessage(_arg1:int, _arg2:String, _arg3:int, _arg4:int, _arg5:String):void{
            var _local6:Object;
            if (this.m_sendWFMessage){
                _local6 = new Object();
                _local6.sessionid = this.m_sessionid;
                _local6.workFlow = _arg2;
                _local6.timeStamp = _arg1;
                _local6.wfLength = _arg3;
                _local6.waitTime = _arg4;
                _local6.type = "gs";
                _local6.waits = _arg5;
                this.queueMessage(_local6);
            };
        }
        private function queueWaitMessage(_arg1:int, _arg2:String, _arg3:String, _arg4:int, _arg5:String, _arg6:String):void{
            var _local7:Object;
            if (this.m_sendWaitMessage){
                _local7 = new Object();
                _local7.sessionid = this.m_sessionid;
                _local7.timeStamp = _arg1;
                _local7.detail = _arg3;
                _local7.MD5 = _arg6;
                _local7.type = "gsWait";
                _local7.waitType = _arg2;
                _local7.waitTime = _arg4;
                _local7.wfs = _arg5;
                this.queueMessage(_local7);
            };
        }
        public function setFPSData(_arg1:Number, _arg2:Number, _arg3:Number):void{
            this.m_f2f = _arg1;
            this.m_mem = _arg3;
            this.m_oef = _arg2;
        }
        private function queueSessionReport():void{
            var _local1:Object;
            var _local2:int;
            if (((this.m_sendSessionMessage) && (!((this.m_loadTime == 0))))){
                _local1 = new Object();
                _local2 = getTimer();
                _local1.type = "gsSession";
                _local1.sessionid = this.m_sessionid;
                _local1.timeStamp = _local2;
                _local1.sessionTime = (_local2 - this.m_sessionStartTime);
                if (this.m_numActiveWaits){
                    _local1.waitTime = (this.m_totalWaitTime + (_local2 - this.m_waitStartTime));
                } else {
                    _local1.waitTime = this.m_totalWaitTime;
                };
                _local1.numClicks = this.m_numClicks;
                _local1.numDialogs = this.m_numPopups;
                _local1.numLoads = this.m_numLoads;
                _local1.numSTPs = this.m_numSTPs;
                _local1.numUnknownWaits = this.m_numUnknownWaits;
                _local1.numWorkFlows = this.m_numWFs;
                if (this.m_numActiveSTPWaits){
                    _local1.STPWaitTime = (this.m_sTPWaitTime + (_local2 - this.m_sTPWaitStartTime));
                } else {
                    _local1.STPWaitTime = this.m_sTPWaitTime;
                };
                _local1.fps = this.m_f2f;
                _local1.mem = this.m_mem;
                _local1.oef = this.m_oef;
                _local1.loadTime = this.m_loadTime;
                this.queueMessage(_local1);
            };
        }
        private function wFStart(_arg1:String):void{
            var _local2:Object;
            var _local4:*;
            var _local5:Object;
            var _local3:int = getTimer();
            if (!this.m_activeWFs[_arg1]){
                _local2 = new Object();
                this.m_numWFs++;
                if (this.m_numActiveWaits){
                    _local2.waitStartTime = _local3;
                } else {
                    _local2.waitStartTime = 0;
                };
                _local2.waitTime = 0;
                _local2.startTime = _local3;
                _local2.name = _arg1;
                _local2.waits = new Array();
                this.m_activeWFs[_arg1] = _local2;
                for (_local4 in this.m_activeWaits) {
                    _local5 = this.m_activeWaits[_local4];
                    _local5.wfs.push(_local2.name);
                    _local2.waits.push(_local5.MD5);
                };
            } else {
                trace(("starting a workflow thats already started:" + _arg1));
            };
        }
        private function wFEnd(_arg1:String):void{
            var _local2:Object;
            var _local4:BloomFilter;
            var _local5:String;
            var _local6:int;
            var _local7:int;
            var _local3:int = getTimer();
            if (this.m_activeWFs[_arg1] != null){
                _local2 = this.m_activeWFs[_arg1];
                if (this.m_numActiveWaits){
                    if (_local2.waitStartTime){
                        _local2.waitTime = (_local2.waitTime + (_local3 - _local2.waitStartTime));
                    } else {
                        _local2.waitTime = (_local2.waitTime + (_local3 - this.m_waitStartTime));
                    };
                };
                _local4 = new BloomFilter(new Array(BloomFilter.DJB, BloomFilter.PJW, BloomFilter.DEK, BloomFilter.JS, BloomFilter.ELF), 20);
                _local5 = "";
                if (_local2.waits.length != 0){
                    _local4.BloomAdd(_local2.waits[0]);
                    _local7 = 1;
                    while (_local7 < _local2.waits.length) {
                        _local4.BloomAdd(_local2.waits[_local7]);
                        _local7++;
                    };
                    _local5 = _local4.toString();
                };
                _local6 = (_local3 - _local2.startTime);
                this.queueWFMessage(_local3, _arg1, _local6, _local2.waitTime, _local5);
                delete this.m_activeWFs[_arg1];
            } else {
                trace(("cant find a workflow to end:" + _arg1));
            };
        }
        private function zaspGetWaitHandle(_arg1:String, _arg2:String):int{
            var _local3:Object = new Object();
            _local3.type = _arg1;
            _local3.detail = _arg2;
            waitHandle = (waitHandle + 1);
            this.m_waitHandleDict[waitHandle] = _local3;
            return (waitHandle);
        }
        private function zaspGetWaitDetails(_arg1:int):Object{
            var _local2:Object;
            if (!this.m_waitHandleDict[_arg1]){
                trace((("handle:" + _arg1.toString()) + " not found in m_waitHandleDict"));
            };
            _local2 = this.m_waitHandleDict[_arg1];
            return (_local2);
        }
        private function zaspRemoveWait(_arg1:int):void{
            delete this.m_waitHandleDict[_arg1];
        }
        private function incrementWaitCounters(_arg1:String):void{
            this.m_numWaits++;
            switch (_arg1){
                case "AMF":
                case "AMF-STP":
                    this.m_numSTPs++;
                    break;
                case "DIALOG":
                    this.m_numDialogs++;
                    break;
                case "ASSET":
                case "HIPRI_ASSET":
                    this.m_numLoads++;
                    break;
                default:
                    this.m_numUnknownWaits++;
            };
        }
        public function zaspWaitStart(_arg1:String, _arg2:String):int{
            var _local4:int;
            var _local5:Object;
            var _local6:*;
            var _local7:Object;
            var _local3:int;
            if (((((this.m_active) && (((!((_arg1 == "ASSET"))) || ((this.m_userWait == true)))))) && (!(this.waitsDisabled())))){
                _local4 = this.zaspGetWaitHandle(_arg1, _arg2);
                _local5 = new Object();
                _local5.start = getTimer();
                _local5.wfs = new Array();
                _local5.detail = _arg2;
                _local5.MD5 = MD5.hash(_arg2);
                this.m_activeWaits[_local4] = _local5;
                if (((this.m_trackAMFTotalWait) || (!((_arg1 == "AMF"))))){
                    this.m_numActiveWaits++;
                    if (!this.m_waitStartTime){
                        this.m_waitStartTime = _local5.start;
                    };
                };
                if ((((_arg1 == "AMF")) || ((_arg1 == "AMF-STP")))){
                    this.m_numActiveSTPWaits++;
                    if (!this.m_sTPWaitStartTime){
                        this.m_sTPWaitStartTime = _local5.start;
                    };
                };
                for (_local6 in this.m_activeWFs) {
                    _local7 = this.m_activeWFs[_local6];
                    _local5.wfs.push(_local7.name);
                    _local7.waits.push(_local5.MD5);
                };
                this.incrementWaitCounters(_arg1);
                _local3 = _local4;
            } else {
                _local3 = 0;
            };
            return (_local3);
        }
        private function updateWFs(_arg1:int):void{
            var _local2:*;
            var _local3:Object;
            var _local4:int;
            for (_local2 in this.m_activeWFs) {
                _local3 = this.m_activeWFs[_local2];
                if (_local3.waitStartTime != 0){
                    _local3.waitTime = (_local3.waitTime + (_arg1 - _local3.waitStartTime));
                    _local3.waitStartTime = 0;
                } else {
                    _local4 = (_arg1 - this.m_waitStartTime);
                    _local3.waitTime = (_local3.waitTime + _local4);
                };
            };
        }
        private function updateWaitState(_arg1:int):void{
            if (this.m_numActiveWaits == 0){
                this.updateWFs(_arg1);
                if (this.m_loadTime != 0){
                    this.m_totalWaitTime = (this.m_totalWaitTime + (_arg1 - this.m_waitStartTime));
                };
                this.m_waitStartTime = 0;
            };
        }
        private function updateSTPWaitState(_arg1:int):void{
            if (this.m_numActiveSTPWaits == 0){
                this.updateWFs(_arg1);
                if (this.m_loadTime != 0){
                    this.m_sTPWaitTime = (this.m_sTPWaitTime + (_arg1 - this.m_sTPWaitStartTime));
                };
                this.m_sTPWaitStartTime = 0;
            };
        }
        public function zaspWaitEnd(_arg1:int):void{
            var _local2:Object;
            var _local3:int;
            var _local4:int;
            var _local5:Object;
            var _local6:String;
            var _local7:int;
            if (this.m_active){
                _local2 = this.m_activeWaits[_arg1];
                if (_local2){
                    _local3 = getTimer();
                    _local4 = (_local3 - _local2.start);
                    _local5 = this.zaspGetWaitDetails(_arg1);
                    if (((this.m_trackAMFTotalWait) || (!((_local5.type == "AMF"))))){
                        this.m_numActiveWaits--;
                        this.updateWaitState(_local3);
                    };
                    if ((((_local5.type == "AMF")) || ((_local5.type == "AMF-STP")))){
                        this.m_numActiveSTPWaits--;
                        this.updateSTPWaitState(_local3);
                    };
                    _local6 = "";
                    if (_local2.wfs.length > 0){
                        _local6 = _local2.wfs[0];
                        _local7 = 1;
                        while (_local7 < _local2.wfs.length) {
                            _local6 = ((_local6 + ",") + _local2.wfs[_local7]);
                            _local7++;
                        };
                    };
                    delete this.m_activeWaits[_arg1];
                    this.queueWaitMessage(_local3, _local5.type, _local5.detail, _local4, _local6, _local2.MD5);
                    this.zaspRemoveWait(_arg1);
                } else {
                    trace(("Failed to find wait to end " + _arg1.toString()));
                };
            };
        }
        public function zaspUserWaitStart():void{
            this.m_userWait = true;
        }
        public function zaspUserWaitEnd():void{
            this.m_userWait = false;
        }
        public function zaspWorkFlowEvent(_arg1:String, _arg2:String):void{
            if (this.m_active){
                if (_arg2 == "BEGIN"){
                    this.wFStart(_arg1);
                } else {
                    if (_arg2 == "END"){
                        this.wFEnd(_arg1);
                    };
                };
            };
        }
        public function waitStateChange(_arg1:Boolean, _arg2:String):void{
            if (this.m_active){
                if (_arg1){
                    this.m_uiWaitHandle = this.zaspWaitStart("JS", _arg2);
                } else {
                    if (this.m_uiWaitHandle){
                        this.zaspWaitEnd(this.m_uiWaitHandle);
                    };
                };
            };
        }

    }
}//package zasp.Classes 
